shell_openstaack_Q_install_file_bak(){
    for file in $*;do
        bak="${file}.bak"
        if [[ ! -e "$bak" ]];then
            cp "$file" "${bak}"
        fi
    done
}
shell_openstaack_Q_install_get_mysql_connection(){
#root用户密码
if [[ -z "$DB_PASS" ]];then
    DB_PASS=000000
fi
#数据库连接变量
mysql_cmd="mysql -uroot -p${DB_PASS} -e "
}
shell_openstaack_Q_install_openstack_endpoint_create(){
    openstack endpoint create --region RegionOne $1 public $2
    chek_status "$?" "创建端点: [ $2 ]_For_[ $1 ]---->public"

    openstack endpoint create --region RegionOne $1 internal $2
    chek_status "$?" "创建端点: [ $2 ]_For_[ $1 ]---->internal"

    openstack endpoint create --region RegionOne $1 admin $2
    chek_status "$?" "创建端点: [ $2 ]_For_[ $1 ]---->admin"
}
shell_openstaack_Q_install_openstack_user_create(){

    #开始创建Demo域
    openstack domain create --description "An Demo Domain" demo
    openstack project create --domain default   --description "Service Project" service
    openstack project create --domain default   --description "Demo Project" demo
    openstack user create --domain default   --password ${DEMO_PASS} demo
    openstack role create user
    openstack role add --project demo --user demo user


echo -e "export OS_PROJECT_DOMAIN_NAME=Default
export OS_USER_DOMAIN_NAME=Default
export OS_PROJECT_NAME=admin
export OS_USERNAME=admin
export OS_PASSWORD=$ADMIN_PASS
export OS_AUTH_URL=http://controller:5000/v3
export OS_IDENTITY_API_VERSION=3
export OS_IMAGE_API_VERSION=2" > /etc/keystone/admin_openrc.sh

echo -e "export OS_PROJECT_DOMAIN_NAME=Default
export OS_USER_DOMAIN_NAME=Default
export OS_PROJECT_NAME=demo
export OS_USERNAME=demo
export OS_PASSWORD=$DEMO_PASS
export OS_AUTH_URL=http://controller:5000/v3
export OS_IDENTITY_API_VERSION=3
export OS_IMAGE_API_VERSION=2" > /etc/keystone/demo_openrc.sh

    source /etc/keystone/admin_openrc.sh
    user='glance nova neutron cinder placement'
    for name in $user;do
        openstack user create --domain default --password ${DEMO_PASS} $name
        chek_status "$?" "在域[ default ]中创建用户: [ $name ]"
        openstack role add --project service --user $name admin
        chek_status "$?" "添加用户: [ $name ]到角色: [ admin ]"
    done

##########################Glance资源创建
    openstack service create --name glance   --description "OpenStack Image" image

    shell_openstaack_Q_install_openstack_endpoint_create   'image'  "http://${HOST_NAME}:9292"


##########################Nova资源创建
    openstack service create --name nova --description "OpenStack Compute" compute
    ##创建端点
    shell_openstaack_Q_install_openstack_endpoint_create 'compute'  "http://${HOST_NAME}:8774/v2.1"

    #创建服务
    openstack service create --name placement --description "Placement API" placement
    #创建端点
    shell_openstaack_Q_install_openstack_endpoint_create 'placement'  "http://${HOST_NAME}:8778"


##########################neutron资源创建
    openstack service create --name neutron  --description "OpenStack Networking" network
    shell_openstaack_Q_install_openstack_endpoint_create 'network'  "http://${HOST_NAME}:9696"



##########################Cinder资源创建
    #创建端点
    # shell_openstaack_Q_install_openstack_endpoint_create 'volumev2'  "http://${HOST_NAME}:8776/v2/%\(project_id\)s"

    #创建端点V3
    # shell_openstaack_Q_install_openstack_endpoint_create 'volumev3'  "http://${HOST_NAME}:8776/v3/%\(project_id\)s"
}
shell_openstaack_Q_install_db_grant(){
    db_user="$1"
    db_name="$2"
    db_pass="$3"
    db_host="localhost controller $4"
    $mysql_cmd "use $db_name;"  > /dev/null 2>&1
    if [[ "$?" -eq '0' ]];then
        if [[ "$2" -eq 'd' ]];then
            $mysql_cmd "drop database $db_name;"
        fi
    fi
    $mysql_cmd "CREATE DATABASE $db_name DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;"
    chek_status "$?" "创建数据库:[ $db_name ]"
    $mysql_cmd "create user  if not exists $db_user;"
    chek_status "$?" "创建数据库用户：[ $db_user ]"
    for host in $db_host;do
        $mysql_cmd "GRANT ALL PRIVILEGES ON $db_name.* TO '$db_user'@'$host' IDENTIFIED BY '$db_pass';"
        chek_status "$?" "授予用户: [ $db_user ]对数据库:[ $db_name ]所有权限并设置登录主机: [ $db_host ]"
        mysql -u$db_user -p$db_pass -e "show databases;"
        chek_status "$?" "用户: [ $db_user ]登录验证"
    done
}
shell_openstaack_Q_install_database_add(){
    ##获取数据库连接信息变量
    shell_openstaack_Q_install_get_mysql_connection
    ##创建数据库列表数组
    db='keystone glance nova nova_api nova_cell0 neutron cinder'
    for db_name in $db;do
        shell_openstaack_Q_install_db_grant "$db_name" "$db_name" "$DB_USER_PASS" "%"
    done
    shell_openstaack_Q_install_db_grant "nova" "nova_api" "$DB_USER_PASS" "%"
    shell_openstaack_Q_install_db_grant  "nova" "nova_cell0" "$DB_USER_PASS" "%"
}
shell_openstaack_Q_install_service_install_db(){
    service_install  'python-openstackclient mariadb-server  rabbitmq-server python-memcached memcached  etcd crudini'

    ######################数据库配置
    echo "[mysqld]
bind-address = ${HOST_IP}
default-storage-engine = innodb
innodb_file_per_table = on
max_connections = 4096
collation-server = utf8_general_ci
character-set-server = utf8" > /etc/my.cnf.d/openstack.cnf
    #初始化数据库(传入ROOT密码)
    install_mariadb__init "$DB_PASS"
    #添加数据库
    shell_openstaack_Q_install_database_add

    ######################rabbitmq配置
    service_start 'rabbitmq-server mariadb'
    rabbitmqctl add_user openstack  000000
    rabbitmqctl set_permissions openstack ".*" ".*" ".*"
    rabbitmq-plugins enable rabbitmq_management
    rabbitmqctl set_user_tags openstack administrator

    ######################memcached配置
    sed -i 's/::1/::1,controller/' /etc/sysconfig/memcached
    service_start 'memcached'
    memcached_status=`netstat -ntlpue | grep memcached | wc -l`
    if [[ "$memcached_status" == '3' ]];then
        green_zt "memcached启动成功"
    else
        red_bg "memcached启动失败"
    fi
    ######################ETCD配置Member
    sed -i -e  "s@.*ETCD_LISTEN_PEER_URLS=.*@ETCD_LISTEN_PEER_URLS=\"http://${HOST_IP}:2380\"@g" \
    -e "s@.*ETCD_LISTEN_CLIENT_URLS=.*@ETCD_LISTEN_CLIENT_URLS=\"http://${HOST_IP}:2379\"@g" \
    -e "s@.*ETCD_NAME=.*@ETCD_NAME=\"${HOST_NAME}\"@g" \
    -e "s@^#\[Clustering\]@\[Clustering\]@g"  /etc/etcd/etcd.conf
    ######################ETCD配置Clustering
    sed -i -e "s@.*ETCD_INITIAL_ADVERTISE_PEER_URLS.*@ETCD_INITIAL_ADVERTISE_PEER_URLS=\"http://${HOST_IP}:2380\"@g" \
    -e "s@.*ETCD_ADVERTISE_CLIENT_URLS.*@ETCD_ADVERTISE_CLIENT_URLS=\"http://${HOST_IP}:2379\"@g" \
    -e  "s@.*ETCD_INITIAL_CLUSTER.*@ETCD_INITIAL_CLUSTER=\"controller=http://${HOST_IP}:2380\"@g" \
    -e "s@.*ETCD_INITIAL_CLUSTER_TOKEN .*@ETCD_INITIAL_CLUSTER_TOKEN=\"etcd-cluster-01\"@g"  /etc/etcd/etcd.conf 
    crudini --set   /etc/etcd/etcd.conf  Clustering ETCD_INITIAL_CLUSTER_STATE \"new\"
    crudini --set   /etc/etcd/etcd.conf  Clustering ETCD_INITIAL_CLUSTER_TOKEN  \"etcd-cluster-01\"
    service_start 'etcd'
    etcd_status=`netstat -natlp | grep etcd | wc -l`
    if [[ "$etcd_status" == 4 ]];then
        green_zt "etcd启动成功"
    else
        red_bg "etcd启动失败"
    fi
}
shell_openstaack_Q_install_service_install_base(){
    shell_openstaack_Q_install_file_bak '/etc/chrony.conf'
    service_install 'chrony bash-completion ntpdate'
    ntpdate time.windwos.com
    sed -i 's/^server/#server/g' /etc/chrony.conf
    SUBNET="`echo $HOST_IP | awk -F '.' '{print $1,$2,$3}' | sed 's/ /./g'`.0/24"
    echo -e "server $HOST_IP iburst
allow $SUBNET" >> /etc/chrony.conf 
    service_start 'chronyd'
    chronyc sources
    chek_status "$?" "时间服务器配置"
    yum update "$?" "系统更新"
    input "基础环境配置完成,请输入[ y ]确认重启系统,回车退出当前程序" 'reb'
    echo -e "\n\nopenstack_base=y" >> /opt/openstack_installer.sh
    if [[ "$reb" == 'y' ]];then
        reboot
    fi
}
shell_openstaack_Q_install_service_install_keystone(){
    service_install ' openstack-keystone httpd mod_wsgi'
    shell_openstaack_Q_install_file_bak '/etc/keystone/keystone.conf' '/etc/httpd/conf/httpd.conf'
    crudini --set /etc/keystone/keystone.conf database connection  mysql+pymysql://keystone:${DB_USER_PASS}@${HOST_NAME}/keystone
    crudini --set /etc/keystone/keystone.conf token provider  fernet
    su -s /bin/sh -c "keystone-manage db_sync" keystone
    chek_status "$?" "keystone数据库初始化"
    keystone-manage fernet_setup --keystone-user keystone --keystone-group keystone
    keystone-manage credential_setup --keystone-user keystone --keystone-group keystone 
    keystone-manage bootstrap --bootstrap-password 000000  \
    --bootstrap-admin-url http://controller:5000/v3/   \
    --bootstrap-internal-url http://controller:5000/v3/   \
    --bootstrap-public-url http://controller:5000/v3/   \
    --bootstrap-region-id RegionOne
    sed -i "s#.*ServerName.*www.*#ServerName controller#g" /etc/httpd/conf/httpd.conf 
    ln -s /usr/share/keystone/wsgi-keystone.conf /etc/httpd/conf.d/
    service_start 'httpd'
    export OS_USERNAME=admin
    export OS_PASSWORD=$ADMIN_PASS
    export OS_PROJECT_NAME=admin
    export OS_USER_DOMAIN_NAME=Default
    export OS_PROJECT_DOMAIN_NAME=Default
    export OS_AUTH_URL=http://controller:5000/v3
    export OS_IDENTITY_API_VERSION=3
    #依次查询域、用户、服务、项目、角色列表
    # openstack domain list
    # openstack user list
    # openstack service list
    # openstack project list
    # openstack role list

    #开始创建用户
    shell_openstaack_Q_install_openstack_user_create



    ####开始进入登录验证
    #默认域登录验证
    unset OS_AUTH_URL OS_PASSWORD
    # openstack --os-auth-url http://controller:35357/v3   \
    # --os-project-domain-name Default \
    # --os-user-domain-name Default   \
    # --os-project-name admin \
    # --os-username admin token issue
    # chek_status "$?" "默认域登录验证"

    # #Demo域登录验证
    # openstack --os-auth-url http://controller:5000/v3   \
    # --os-project-domain-name Default \
    # --os-user-domain-name Default   \
    # --os-project-name demo \
    # --os-username demo token issue
    # chek_status "$?" "Demo域登录验证"


    unset OS_AUTH_URL OS_PASSWORD
    source /etc/keystone/admin_openrc.sh
    openstack token issue
    chek_status "$?" "Admin用户变量声明配置"


    unset OS_AUTH_URL OS_PASSWORD
    source /etc/keystone/demo_openrc.sh
    openstack token issue
    chek_status "$?" "Demo用户变量声明配置"
}

shell_openstaack_Q_install_service_install_glance(){
    source /etc/keystone/admin_openrc.sh
    service_install 'openstack-glance'
    shell_openstaack_Q_install_file_bak '/etc/glance/glance-api.conf' '/etc/glance/glance-registry.conf'
    crudini --set /etc/glance/glance-api.conf database connection  mysql+pymysql://glance:${DB_USER_PASS}@${HOST_NAME}/glance

    crudini --set /etc/glance/glance-api.conf keystone_authtoken auth_uri http://${HOST_NAME}:5000

    crudini --set /etc/glance/glance-api.conf keystone_authtoken auth_url http://${HOST_NAME}:35357

    crudini --set /etc/glance/glance-api.conf keystone_authtoken memcached_servers  ${HOST_NAME}:11211

    crudini --set /etc/glance/glance-api.conf keystone_authtoken auth_type password

    crudini --set /etc/glance/glance-api.conf keystone_authtoken project_domain_name Default

    crudini --set /etc/glance/glance-api.conf keystone_authtoken user_domain_name Default

    crudini --set /etc/glance/glance-api.conf keystone_authtoken project_name service

    crudini --set /etc/glance/glance-api.conf keystone_authtoken username glance

    crudini --set /etc/glance/glance-api.conf keystone_authtoken password ${DEMO_PASS}

    crudini --set /etc/glance/glance-api.conf paste_deploy flavor keystone

    crudini --set /etc/glance/glance-api.conf glance_store stores file,http
    crudini --set /etc/glance/glance-api.conf glance_store default_store file
    crudini --set /etc/glance/glance-api.conf glance_store filesystem_store_datadir /var/lib/glance/images/

    crudini --set /etc/glance/glance-registry.conf database connection  mysql+pymysql://glance:${DEMO_PASS}@${HOST_NAME}/glance

    crudini --set /etc/glance/glance-registry.conf keystone_authtoken auth_uri http://controller:5000
    crudini --set /etc/glance/glance-registry.conf keystone_authtoken auth_url http://controller:35357
    crudini --set /etc/glance/glance-registry.conf keystone_authtoken memcached_servers controller:11211
    crudini --set /etc/glance/glance-registry.conf keystone_authtoken auth_type password
    crudini --set /etc/glance/glance-registry.conf keystone_authtoken project_domain_name default
    crudini --set /etc/glance/glance-registry.conf keystone_authtoken user_domain_name default
    crudini --set /etc/glance/glance-registry.conf keystone_authtoken project_name service
    crudini --set /etc/glance/glance-registry.conf keystone_authtoken username glance
    crudini --set /etc/glance/glance-registry.conf keystone_authtoken password $DEMO_PASS


    crudini --set /etc/glance/glance-registry.conf paste_deploy flavor keystone
    crudini --set /etc/glance/glance-registry.conf paste_deploy config_file  /usr/share/glance/glance-registry-dist-paste.ini

    su -s /bin/sh -c "glance-manage db_sync" glance
    chek_status "$?" "glance组件初始化数据库"
    service_start 'openstack-glance-api.service   openstack-glance-registry.service'
    source /etc/keystone/admin_openrc.sh
    if [[ -e './cirros-0.3.4-x86_64-disk.img' ]];then
        md=`md5sum cirros-0.3.4-x86_64-disk.img | awk '{print $1}'`
        if [[ "$md" -eq 'ee1eca47dc88f4879d8a229cc70a07c6' ]];then
            green_zt "MD5校验成功"
        else
            rm -f cirros-0.3.4-x86_64-disk.img
            if [[ -e '/usr/bin/wget' ]];then
                green_zt 'wget已安装'
            else
                service_install 'wget'
            fi
            wget http://download.cirros-cloud.net/0.3.4/cirros-0.3.4-x86_64-disk.img
            chek_status "$?" "文件下载: [ wget http://download.cirros-cloud.net/0.3.4/cirros-0.3.4-x86_64-disk.img ]"
        fi

    else
        if [[ -e '/usr/bin/wget' ]];then
            green_zt 'wget已安装'
        else
            service_install 'wget'
        fi
        wget http://download.cirros-cloud.net/0.3.4/cirros-0.3.4-x86_64-disk.img
        chek_status "$?" "文件下载: [ wget http://download.cirros-cloud.net/0.3.4/cirros-0.3.4-x86_64-disk.img ]"
    fi
    if [[ -e './cirros-0.3.4-x86_64-disk.img' ]];then
        source /etc/keystone/admin_openrc.sh
        openstack image create "cirros"   --file cirros-0.3.4-x86_64-disk.img  --disk-format qcow2 --container-format bare   --public
        chek_status "$?" "镜像上传:[ openstack image create \"cirros\"   --file cirros-0.3.4-x86_64-disk.img  --disk-format qcow2 --container-format bare   --public"
    else
        green_zt '镜像文件上传跳过'
    fi
}
shell_openstaack_Q_install_service_install_nova_compute(){
    service_install 'openstack-nova-compute'
    crudini --set /etc/nova/nova.conf  DEFAULT enabled_apis osapi_compute,metadata
    crudini --set /etc/nova/nova.conf  DEFAULT transport_url  rabbit://openstack:${DEMO_PASS}@${HOST_NAME}
    crudini --set /etc/nova/nova.conf  DEFAULT my_ip ${NODE_HOST_IP}
    crudini --set /etc/nova/nova.conf  DEFAULT use_neutron True
    crudini --set /etc/nova/nova.conf  DEFAULT firewall_driver nova.virt.firewall.NoopFirewallDriver
    
    crudini --set /etc/nova/nova.conf api auth_strategy keystone
    
    
    crudini --set /etc/nova/nova.conf keystone_authtoken auth_url http://${HOST_NAME}:5000/v3
    crudini --set /etc/nova/nova.conf keystone_authtoken memcached_servers ${HOST_NAME}:11211
    crudini --set /etc/nova/nova.conf keystone_authtoken auth_type password
    crudini --set /etc/nova/nova.conf keystone_authtoken  project_domain_name default
    crudini --set /etc/nova/nova.conf keystone_authtoken  user_domain_name default
    crudini --set /etc/nova/nova.conf keystone_authtoken  project_name service
    crudini --set /etc/nova/nova.conf keystone_authtoken  username nova
    crudini --set /etc/nova/nova.conf keystone_authtoken  password $DEMO_PASS
    
    
    
    crudini --set /etc/nova/nova.conf vnc  enabled True
    crudini --set /etc/nova/nova.conf vnc server_listen  0.0.0.0
    crudini --set /etc/nova/nova.conf vnc server_proxyclient_address \$my_ip
    crudini --set /etc/nova/nova.conf vnc novncproxy_base_url http://${HOST_NAME}:6080/vnc_auto.html

    crudini --set /etc/nova/nova.conf glance api_servers  http://${HOST_NAME}:9292
    crudini --set /etc/nova/nova.conf oslo_concurrency lock_path /var/lib/nova/tmp


    crudini --set /etc/nova/nova.conf placement os_region_name RegionOne
    crudini --set /etc/nova/nova.conf placement project_domain_name Default
    crudini --set /etc/nova/nova.conf placement project_name service
    crudini --set /etc/nova/nova.conf placement auth_type password
    crudini --set /etc/nova/nova.conf placement user_domain_name Default
    crudini --set /etc/nova/nova.conf placement auth_url http://${HOST_NAME}:5000/v3
    crudini --set /etc/nova/nova.conf placement username placement
    crudini --set /etc/nova/nova.conf placement password ${DEMO_PASS}

    






}
shell_openstaack_Q_install_service_install_nova(){
    source /etc/keystone/admin_openrc.sh 


    service_install 'openstack-nova-api openstack-nova-conductor   
    openstack-nova-console openstack-nova-novncproxy   
    openstack-nova-scheduler openstack-nova-placement-api'
    if [[ ! -e '/etc/nova/nova.conf.bak' ]];then
        cp /etc/nova/nova.conf  /etc/nova/nova.conf.bak
    fi

    #配置默认连接信息
    crudini --set /etc/nova/nova.conf DEFAULT enabled_apis  osapi_compute,metadata
    crudini --set /etc/nova/nova.conf DEFAULT transport_url rabbit://openstack:${DEMO_PASS}@${HOST_NAME}
    crudini --set /etc/nova/nova.conf DEFAULT my_ip ${HOST_IP}
    crudini --set /etc/nova/nova.conf DEFAULT use_neutron  True 
    crudini --set /etc/nova/nova.conf DEFAULT firewall_driver nova.virt.firewall.NoopFirewallDriver
    

    #配置数据库连接信息

    crudini --set /etc/nova/nova.conf api_database connection  mysql+pymysql://nova:${DEMO_PASS}@${HOST_NAME}/nova_api
    crudini --set /etc/nova/nova.conf database connection mysql+pymysql://nova:${DEMO_PASS}@${HOST_NAME}/nova
    crudini --set /etc/nova/nova.conf api auth_strategy keystone

    #配置认证信息
    crudini --set /etc/nova/nova.conf keystone_authtoken auth_url http://${HOST_NAME}:5000/v3
    crudini --set /etc/nova/nova.conf keystone_authtoken memcached_servers ${HOST_NAME}:11211
    crudini --set /etc/nova/nova.conf keystone_authtoken auth_type  password
    crudini --set /etc/nova/nova.conf keystone_authtoken project_domain_name default
    crudini --set /etc/nova/nova.conf keystone_authtoken user_domain_name default
    crudini --set /etc/nova/nova.conf keystone_authtoken project_name service
    crudini --set /etc/nova/nova.conf keystone_authtoken username nova
    crudini --set /etc/nova/nova.conf keystone_authtoken password  ${DEMO_PASS}

    #配置VNC
    crudini --set /etc/nova/nova.conf vnc enabled true
    crudini --set /etc/nova/nova.conf vnc server_listen '$my_ip'
    crudini --set /etc/nova/nova.conf vnc server_proxyclient_address '$my_ip'

    #配置glance
    crudini --set /etc/nova/nova.conf glance api_servers http://${HOST_NAME}:9292

    #配置锁定路径
    crudini --set /etc/nova/nova.conf oslo_concurrency lock_path '/var/lib/nova/tmp'

    #配置placement
    crudini --set /etc/nova/nova.conf  placement os_region_name RegionOne
    crudini --set /etc/nova/nova.conf  placement project_domain_name Default
    crudini --set /etc/nova/nova.conf  placement project_name service
    crudini --set /etc/nova/nova.conf  placement auth_type password
    crudini --set /etc/nova/nova.conf  placement user_domain_name Default
    crudini --set /etc/nova/nova.conf  placement auth_url  http://${HOST_NAME}:5000/v3
    crudini --set /etc/nova/nova.conf  placement username placement
    crudini --set /etc/nova/nova.conf  placement password ${DEMO_PASS}

    #写入配置参数
   cp /etc/httpd/conf.d/00-nova-placement-api.conf /etc/httpd/conf.d/00-nova-placement-api.conf.bak
echo -e "\n<Directory /usr/bin>
\t<IfVersion >= 2.4>
\t\tRequire all granted
\t</IfVersion>
\t<IfVersion < 2.4>
\t\tOrder allow,deny
\t\tAllow from all
 \t</IfVersion>
 </Directory>" >> /etc/httpd/conf.d/00-nova-placement-api.conf 
    service_start 'httpd'
    su -s /bin/sh -c "nova-manage api_db sync" nova
    chek_status "$?" "初始化数据库: [ su -s /bin/sh -c \"nova-manage api_db sync\" nova ]"

    su -s /bin/sh -c "nova-manage cell_v2 map_cell0" nova
    chek_status "$?" "初始化数据库: [ su -s /bin/sh -c \"nova-manage cell_v2 map_cell0\" nova ]"

    su -s /bin/sh -c "nova-manage cell_v2 create_cell --name=cell1 --verbose" nova
    chek_status "$?" "初始化数据库: [ su -s /bin/sh -c \"nova-manage cell_v2 create_cell --name=cell1 --verbose\" nova ]"

    su -s /bin/sh -c "nova-manage db sync" nova
    chek_status "$?" "初始化数据库: [ su -s /bin/sh -c \"nova-manage db sync\" nova ]"

    service_start 'openstack-nova-api.service   openstack-nova-consoleauth.service openstack-nova-scheduler.service   openstack-nova-conductor.service openstack-nova-novncproxy.service'

    nova-manage cell_v2 list_cells
    chek_status "$?" "Nova组件安装配置"
}
neutron_mode_gre(){
crudini --set /etc/neutron/neutron.conf DEFAULT service_plugins router,lbaas,firewall
crudini --set /etc/neutron/neutron_lbaas.conf service_providers service_provider LOADBALANCER:Haproxy:neutron_lbaas.services.loadbalancer.drivers.haproxy.plugin_driver.HaproxyOnHostPluginDriver:default
crudini --set /etc/neutron/lbaas_agent.ini DEFAULT device_driver neutron_lbaas.services.loadbalancer.drivers.haproxy.namespace_driver.HaproxyNSDriver
crudini --set /etc/neutron/lbaas_agent.ini DEFAULT interface_driver neutron.agent.linux.interface.OVSInterfaceDriver
crudini --set /etc/neutron/lbaas_agent.ini haproxy user_group haproxy

crudini --set /etc/neutron/neutron.conf service_providers FIREWALL:Iptables:neutron.agent.linux.iptables_firewall.OVSHybridIptablesFirewallDriver:default
crudini --set /etc/neutron/fwaas_driver.ini fwaas driver neutron_fwaas.services.firewall.drivers.linux.iptables_fwaas.IptablesFwaasDriver
crudini --set /etc/neutron/fwaas_driver.ini fwaas enabled True

crudini --set /etc/neutron/plugins/ml2/ml2_conf.ini ml2 tenant_network_types  gre
crudini --set /etc/neutron/plugins/ml2/ml2_conf.ini ml2_type_gre tunnel_id_ranges  1:1000
#设置租户网络的类型为gre
#gre为private network 提供的标识范围

ovs-vsctl add-br br-ex
check_status "$?" "添加网桥---> [ $INTERFACE_NAME ]"
#添加一个名为br-ex的网桥
ovs-vsctl add-port br-ex $INTERFACE_NAME 
check_status "$?" "添加接口---> [ $INTERFACE_NAME ]"
#为网桥br-ex添加一个名为$INTERFACE_NAME 的接口

#为文件/etc/sysconfig/network-scripts/ifcfg-$INTERFACE_NAME 覆盖写入以下内容
#物理设备的名字为$INTERFACE_NAME
#网络类型为Ethernet
#禁用dhcp	
#引导时激活该设备
cat > /etc/sysconfig/network-scripts/ifcfg-$INTERFACE_NAME <<EOF
DEVICE=$INTERFACE_NAME
TYPE=Ethernet
BOOTPROTO=none
ONBOOT=yes
EOF


systemctl restart network
crudini --set  /etc/neutron/l3_agent.ini DEFAULT  external_network_bridge  br-ex
crudini --set  /etc/neutron/plugins/ml2/openvswitch_agent.ini ovs bridge_mappings  physnet1:br-ex
crudini --set  /etc/neutron/plugins/ml2/openvswitch_agent.ini agent tunnel_types  gre
crudini --set  /etc/neutron/plugins/ml2/openvswitch_agent.ini ovs local_ip $HOST_IP
crudini --set  /etc/neutron/plugins/ml2/openvswitch_agent.ini ovs  enable_tunneling True
crudini --set  /etc/neutron/plugins/ml2/openvswitch_agent.ini ovs bridge_mappings external:br-ex

neutron-db-manage --service lbaas upgrade head
neutron-db-manage --subproject neutron-fwaas upgrade head
    service_start 'neutron-server neutron-l3-agent neutron-openvswitch-agent neutron-lbaas-agent'
}
shell_openstaack_Q_install_service_install_neutron(){
    service_install 'openstack-neutron openstack-neutron-ml2   openstack-neutron-linuxbridge ebtables'

    #修改database
    crudini --set /etc/neutron/neutron.conf database connection mysql+pymysql://neutron:${DEMO_PASS}@${HOST_NAME}/neutron

    #DEFAULT配置
    crudini --set /etc/neutron/neutron.conf DEFAULT core_plugin ml2 
    crudini --set /etc/neutron/neutron.conf DEFAULT service_plugins router
    crudini --set /etc/neutron/neutron.conf DEFAULT allow_overlapping_ips true
    crudini --set /etc/neutron/neutron.conf DEFAULT transport_url rabbit://openstack:${DEMO_PASS}@${HOST_NAME}
    crudini --set /etc/neutron/neutron.conf DEFAULT auth_strategy keystone 
    crudini --set /etc/neutron/neutron.conf DEFAULT notify_nova_on_port_status_changes true 
    crudini --set /etc/neutron/neutron.conf DEFAULT notify_nova_on_port_data_changes  true

    #配置身份认证
    crudini --set /etc/neutron/neutron.conf keystone_authtoken auth_uri http://${HOST_NAME}:5000
    crudini --set /etc/neutron/neutron.conf keystone_authtoken auth_url http://${HOST_NAME}:35357
    crudini --set /etc/neutron/neutron.conf keystone_authtoken memcached_servers ${HOST_NAME}:11211
    crudini --set /etc/neutron/neutron.conf keystone_authtoken auth_type password
    crudini --set /etc/neutron/neutron.conf keystone_authtoken project_domain_name  default
    crudini --set /etc/neutron/neutron.conf keystone_authtoken user_domain_name default
    crudini --set /etc/neutron/neutron.conf keystone_authtoken project_name service
    crudini --set /etc/neutron/neutron.conf keystone_authtoken username neutron
    crudini --set /etc/neutron/neutron.conf keystone_authtoken password ${DEMO_PASS}

    #配置nova
    crudini --set /etc/neutron/neutron.conf nova auth_url http://${HOST_NAME}:35357
    crudini --set /etc/neutron/neutron.conf nova auth_type password
    crudini --set /etc/neutron/neutron.conf nova project_domain_name  default
    crudini --set /etc/neutron/neutron.conf nova user_domain_name default
    crudini --set /etc/neutron/neutron.conf nova region_name RegionOne
    crudini --set /etc/neutron/neutron.conf nova project_name service
    crudini --set /etc/neutron/neutron.conf nova username nova
    crudini --set /etc/neutron/neutron.conf nova password ${DEMO_PASS}

    #配置oslo_concurrency
    crudini --set /etc/neutron/neutron.conf noslo_concurrency lock_path /var/lib/neutron/tmp




    #安全组
    crudini --set  /etc/neutron/plugins/ml2/ml2_conf.ini securitygroup enable_ipset true


    crudini --set  /etc/neutron/plugins/ml2/linuxbridge_agent.ini  securitygroup enable_security_group true
    crudini --set  /etc/neutron/plugins/ml2/linuxbridge_agent.ini  securitygroup firewall_driver neutron.agent.linux.iptables_firewall.IptablesFirewallDriver

    #网桥
    crudini --set  /etc/neutron/plugins/ml2/linuxbridge_agent.ini   linux_bridge physical_interface_mappings "provider:${NET_CARD}"

    #xvlan
    crudini --set  /etc/neutron/plugins/ml2/ml2_conf.ini  vxlan enable_vxlan true
    crudini --set  /etc/neutron/plugins/ml2/ml2_conf.ini  vxlan local_ip ${HOST_IP}
    crudini --set  /etc/neutron/plugins/ml2/ml2_conf.ini  vxlan l2_population true

echo 'net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1' > /etc/sysctl.conf 
    sysctl -p

    #l3_agent.ini
    crudini --set  /etc/neutron/l3_agent.ini DEFAULT interface_driver linuxbridge

    #DHCP
    crudini --set  /etc/neutron/dhcp_agent.ini DEFAULT interface_driver linuxbridge
    crudini --set  /etc/neutron/dhcp_agent.ini DEFAULT dhcp_driver  neutron.agent.linux.dhcp.Dnsmasq
    crudini --set  /etc/neutron/dhcp_agent.ini DEFAULT enable_isolated_metadata true

    #元数据
    crudini --set  /etc/neutron/metadata_agent.ini DEFAULT nova_metadata_host ${HOST_NAME}
    crudini --set  /etc/neutron/metadata_agent.ini DEFAULT metadata_proxy_shared_secret  ${DEMO_PASS}
    
    #配置计算服务以使用网络服务
    crudini --set  /etc/nova/nova.conf  neutron url http://${HOST_NAME}:9696
    crudini --set  /etc/nova/nova.conf  neutron auth_url http://${HOST_NAME}:35357
    crudini --set  /etc/nova/nova.conf  neutron auth_type password
    crudini --set  /etc/nova/nova.conf  neutron project_domain_name default
    crudini --set  /etc/nova/nova.conf  neutron user_domain_name default
    crudini --set  /etc/nova/nova.conf  neutron region_name RegionOne
    crudini --set  /etc/nova/nova.conf  neutron project_name  service
    crudini --set  /etc/nova/nova.conf  neutron username neutron
    crudini --set  /etc/nova/nova.conf  neutron password ${DEMO_PASS}
    crudini --set  /etc/nova/nova.conf  neutron service_metadata_proxy true
    crudini --set  /etc/nova/nova.conf  neutron metadata_proxy_shared_secret ${DEMO_PASS}

    #创建软连接
    ln -s /etc/neutron/plugins/ml2/ml2_conf.ini /etc/neutron/plugin.ini
    #更新数据库
    su -s /bin/sh -c "neutron-db-manage --config-file /etc/neutron/neutron.conf --config-file /etc/neutron/plugins/ml2/ml2_conf.ini upgrade head" neutron
    chek_status "$?" "初始化网络组件数据库"


    #服务启动
    service_start ' openstack-nova-api.service
    neutron-server.service   neutron-linuxbridge-agent.service  
    neutron-dhcp-agent.service   neutron-metadata-agent.service
    neutron-l3-agent.service'
    #至此，控制节点的网络服务就配置完成了

}


shell_openstaack_Q_install_service_install_cinder(){
    #创建资源
    openstack service create --name cinderv2 --description "OpenStack Block Storage" volumev2
    openstack service create --name cinderv3 --description "OpenStack Block Storage" volumev3



    #安装服务
    service_install 'openstack-cinder'

    #修改配置-数据库
    crudini --set /etc/cinder/cinder.conf database connection mysql+pymysql://cinder:${DB_USER_PASS}@${HOST_NAME}/cinder

    #修改配置-keystone
    crudini --set /etc/cinder/cinder.conf keystone_authtoken auth_uri http://${HOST_NAME}:5000
    crudini --set /etc/cinder/cinder.conf keystone_authtoken auth_url http://${HOST_NAME}:5000
    crudini --set /etc/cinder/cinder.conf keystone_authtoken memcached_servers ${HOST_NAME}:11211
    crudini --set /etc/cinder/cinder.conf keystone_authtoken auth_type password
    crudini --set /etc/cinder/cinder.conf keystone_authtoken project_domain_id default
    crudini --set /etc/cinder/cinder.conf keystone_authtoken user_domain_id default
    crudini --set /etc/cinder/cinder.conf keystone_authtoken project_name service
    crudini --set /etc/cinder/cinder.conf keystone_authtoken username cinder
    crudini --set /etc/cinder/cinder.conf keystone_authtoken password ${DEMO_PASS}

    #修改配置-DEFAULT
    crudini --set /etc/cinder/cinder.conf DEFAULT transport_url  rabbit://openstack:${DEMO_PASS}@${HOST_NAME}
    crudini --set /etc/cinder/cinder.conf DEFAULT auth_strategy keystone 
    crudini --set /etc/cinder/cinder.conf DEFAULT my_ip ${HOST_IP}

    #修改配置-锁
    crudini --set /etc/cinder/cinder.conf oslo_concurrency lock_path  /var/lib/cinder/tmp

    #修改配置
    crudini --set  /etc/nova/nova.conf cinder os_region_name RegionOne

    #初始化数据库
    su -s /bin/sh -c "cinder-manage db sync" cinder
    chek_status "$?" "数据库初始化:[ cinder ]"
}
shell_openstaack_Q_install_service_install_dashboard(){
    service_install 'openstack-dashboard'
    cp /etc/openstack-dashboard/local_settings /etc/openstack-dashboard/local_settings.bak
    sed -i "s#OPENSTACK_HOST.*=.*#OPENSTACK_HOST = \"${HOST_NAME}\"#g" /etc/openstack-dashboard/local_settings
    sed -i "s#OPENSTACK_KEYSTONE_DEFAULT_ROLE.*#OPENSTACK_KEYSTONE_DEFAULT_ROLE = 'user'#g" /etc/openstack-dashboard/local_settings
    sed -i "s#ALLOWED_HOSTS.*#ALLOWED_HOSTS = ['horizon.example.com', 'localhost','\*']#g" /etc/openstack-dashboard/local_settings
    sed -i "164,169s/^/#/" /etc/openstack-dashboard/local_settings
    sed -i "158,163s/^#//" /etc/openstack-dashboard/local_settings
    
    #在SECRET_KEY=开头的匹配行另起一行，插入新数据
    sed -i "/SECRET_KEY=/a\SESSION_ENGINE = 'django.contrib.sessions.backends.cache'" /etc/openstack-dashboard/local_settings
    sed -i "s#127.0.0.1:11211#${HOST_NAME}:11211#g"  /etc/openstack-dashboard/local_settings

    sed -i "64,70s/^#//" /etc/openstack-dashboard/local_settings
    sed -i "65s/^/#/" /etc/openstack-dashboard/local_settings
    sed -i "69s/^/#/" /etc/openstack-dashboard/local_settings
    
    #启用域支持
    sed -i "s/^#OPENSTACK_KEYSTONE_MULTIDOMAIN_SUPPORT.*/OPENSTACK_KEYSTONE_MULTIDOMAIN_SUPPORT = 'true'/g" /etc/openstack-dashboard/local_settings

    #通过仪表板创建的用户配置为默认域
    sed -i 's/#OPENSTACK_KEYSTONE_DEFAULT_DOMAIN/OPENSTACK_KEYSTONE_DEFAULT_DOMAIN/g' /etc/openstack-dashboard/local_settings 

   sed -i "/WSGISocketPrefix/a\WSGIApplicationGroup %{GLOBAL}" /etc/httpd/conf.d/openstack-dashboard.conf 
   service_start 'httpd.service memcached.service'

}
shell_openstaack_Q_install_host_config(){
    ip_controller=`hostname -I | grep -oP "$HOST_IP"`
    ip_compute=`hostname -I | grep -oP "$NODE_HOST_IP"`
    if [[ "$ip_controller" == "$HOST_IP" ]];then
        red_z_green_z '检测到当前IP与与配置的控制节点IP一致' "已设置当前主机为控制节点[ $HOST_NAME ]"
        type='controller'
        hostnamectl set-hostname $HOST_NAME
    else
        if [[ "$ip_compute" == "$NODE_HOS_IP" ]];then
            red_z_green_z '检测到当前IP与与配置的计算节点IP一致' "已设置当前主机为计算节点[ $NODE_HOST_NAME ]"
            type='compute'
            hostnamectl set-hostname $NODE_HOST_NAME
        else
            red_bg '无法判断当前主机节点类型，请修改配置文件[ config/openstack.sh ]'
            exit 2
        fi
    fi
    echo "127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
$HOST_IP $HOST_NAME
$NODE_HOST_IP $NODE_HOST_NAME" > /etc/hosts
}

##正式安装函数步骤

shell_openstaack_Q_install_install_openstack_controller(){
if [[ ! -e '/opt/install_log.sh' ]];then
    echo 'shell_openstaack_Q_install_service_install_db
shell_openstaack_Q_install_service_install_keystone
shell_openstaack_Q_install_service_install_glance
shell_openstaack_Q_install_service_install_neutron'  > /opt/install_log.sh
fi
    Entering "数据库及存储相关基础组件安装"
    shell_openstaack_Q_install_service_install_db #开始安装数据库及消息队列等
    sed -i 's/shell_openstaack_Q_install_service_install_db//' /opt/install_log.sh
  


    Entering "Keystone组件安装"
    shell_openstaack_Q_install_service_install_keystone
    sed -i 's/shell_openstaack_Q_install_service_install_keystone//' /opt/install_log.sh

    Entering "Glance组件安装"
    shell_openstaack_Q_install_service_install_glance
    sed -i 's/shell_openstaack_Q_install_service_install_glance//' /opt/install_log.sh

    Entering "Nova组件安装"
    shell_openstaack_Q_install_service_install_nova
    sed -i 's/shell_openstaack_Q_install_service_install_nova//' /opt/install_log.sh

    Entering "neutron组件安装"
    shell_openstaack_Q_install_service_install_neutron
    sed -i 's/shell_openstaack_Q_install_service_install_neutron//' /opt/install_log.sh

    Entering "dashboard组件安装"
    shell_openstaack_Q_install_service_install_dashboard
    sed -i 's/shell_openstaack_Q_install_service_install_dashboard//' /opt/install_log.sh

    Entering "Cinder组件安装"
    shell_openstaack_Q_install_service_install_cinder
    sed -i 's/shell_openstaack_Q_install_service_install_cinder//' /opt/install_log.sh
   dashboard_status=`netstat -natlp | grep httpd | wc -l`
   if [[ $dashboard_status == 4 ]];then
        green_zt "OpenStack配置成功"
        red_z_green_z "访问地址:" "\nhttp://${HOST_IP}/dashboard"
        red_z_green_z "登录域:" '\n[default]'
        red_z_green_z "登录用户:" '\n[admin]'
        red_z_green_z "登录密码:" "\n[ $ADMIN_PASS ]"
    fi
}
shell_openstaack_Q_install_install_openstack_compute(){
    Entering "Nova组件安装"
    shell_openstaack_Q_install_service_install_nova_compute
    sed -i 's/shell_openstaack_Q_install_service_install_nova//' /opt/install_log.sh

    Entering "neutron组件安装"
    shell_openstaack_Q_install_service_install_neutron
    sed -i 's/shell_openstaack_Q_install_service_install_neutron//' /opt/install_log.sh
}